import * as d3 from "d3"
import moment from "moment"

const padding = 20
const extendDay = 10
const _everyDay = 10
const tickSize = 50
const dayX2Bottom = tickSize * 3 - padding


function removeAll(chart) {
    chart.selectAll(".x-axis").remove()
}

function tickCellFormat(d0, d1) {
    if (d0 === d1) {
        return `${d0}日`
    }

    return `${d0}日~${d1}日`
}

function tickCellWidth(fontSize) {
    let cellTitle = tickCellFormat("30", "31")
    let cellWidth = cellTitle.length * (fontSize + 4)
    return cellWidth
}

function calcChartWidth(fontSize, totalCount) {
    let wCount = Math.ceil(totalCount / 2)
    let cw = tickCellWidth(fontSize)
    let tw = cw * wCount
    return tw
}


export function xHeader(chart, params) {
    removeAll(chart)

    const {
        fontSize,
        startTime,
        endTime,
        totalDayCount,
        step,
        height,
        everyDay = _everyDay
    } = params


    // let chartWidth = calcChartWidth(fontSize, totalDayCount)
    let chartWidth = 5000, chartHeight = height;
    console.log("chartWidth:%s", chartWidth)
    chart.attr("width", chartWidth)
    chart.attr("height", height)



    const showStartTime = moment(startTime).add("day", -1 * extendDay).toDate()
    const showEndTime = moment(endTime).add("day", extendDay).toDate()

    const colorScale = d3.scaleOrdinal(d3.schemeCategory10)

    const monthMap = computeMothMap(showStartTime, showEndTime)
    const dayTicks = computeDayTicks(everyDay, monthMap);
    const monthTicks = computeMonthTicks(monthMap)
    const yearTicks = computeYearTicks(monthMap)

    const xStart = 20, xEnd = chartWidth - xStart * 2



    console.log("showEndTime", moment(showEndTime).format("YYYY-MM-DD HH:mm:ss"), dayTicks)


    //2、创建一个X坐标轴
    const xScale = d3.scaleTime([showStartTime, showEndTime], [xStart, xEnd]);
    // x.ticks(d3.utcMinute.every(24 * 60));
    const dayAxis = d3.axisTop(xScale).tickValues(dayTicks).tickSize(tickSize)

    const dx = chart.append("g")
        .attr("class", "x-axis day-axis")
        .attr("transform", `translate(0,${height - dayX2Bottom})`)
        .call(dayAxis);


    const positionComptedFn = dx.node().__axis

    formatTickValue(dx, (currentDate, nextDate) => {
        let m0 = moment(currentDate).format("MM")
        let d0 = moment(currentDate).format("DD")
        // let d1 = moment(nextDate).add("day", -1).format("DD")
        // let constClassName = "day-tick-lbl"
        // let className = "day-tick-range", tikStr = ""
        // if (d0 === d1) {
        //     tikStr = d0
        //     className = "day-tick-signle"
        // } else {
        //     tikStr = `${d0}~${d1}`
        // }
        return `${m0}-${d0}`

        // return `<div class="${constClassName} ${className}"> ${tikStr}</div>`
    })


    // const monthAxis = d3.axisTop(xScale).tickValues(monthTicks).tickSize(tickSize)
    // const mx = chart.append("g").classed("x-axis month-axis", true)
    //     .attr("transform", `translate(0,${height - dayX2Bottom - tickSize})`)
    //     .call(monthAxis);

    // formatTickValue(mx, (currentDate) => {
    //     let d0 = moment(currentDate).format("YYYY-MM")
    //     return `${d0}月`
    // })


    // const yearAxis = d3.axisTop(xScale).tickValues(yearTicks).tickSize(tickSize)
    // const yx = chart.append("g").classed("x-axis year-axis", true)
    //     .attr("transform", `translate(0,${height - dayX2Bottom - tickSize * 2})`)
    //     .call(yearAxis);

    // formatTickValue(yx, (currentDate) => {
    //     let d0 = moment(currentDate).format("YYYY")
    //     return `${d0}年`
    // })

    // const topAxis = d3.axisTop(xScale).tickValues([showStartTime, showEndTime]).tickSize(0)
    // const topLine = chart.append("g").classed("x-axis top-line", true)
    //     .attr("transform", `translate(0,${height - dayX2Bottom - tickSize * 3})`)
    //     .call(topAxis);

    // formatTickValue(topLine, () => "")

    function formatTickValue(axis, formatCallback) {
        axis.selectAll(".tick").each(function (d, index, nodes) {
            let nextData = nodes[index + 1]?.__data__ || showEndTime
            let distance = positionComptedFn(nextData) - positionComptedFn(d)
            distance *= 0.5
            d3.select(this)
                .select("text")
                .classed('axis-label', true)
                // .attr("text-anchor", "middle")
                // .attr("transform", `translate(${distance},${(tickSize + fontSize) * 0.5})`)
                .text((d) => {
                    // if (distance === 0) return ""
                    return formatCallback(d, nextData)
                })

        })
    }

    function computeMothMap(begin, end) {
        let mCount = moment(end).startOf("month").diff(moment(begin).startOf("month"), "month");
        const monthMap = {}

        let startMonth = moment(begin).format("YYYY-MM")
        let endMonth = moment(end).format("YYYY-MM")

        for (let i = 0; i <= mCount; i++) {
            let cm = moment(begin).add('month', i).format("YYYY-MM");

            let mStartDay = moment(cm).startOf('month');//当前月开始时间
            let mEndDay = moment(cm).endOf('month');

            if (cm === startMonth && mStartDay.isBefore(moment(begin))) {
                mStartDay = moment(begin)
            }

            if (cm === endMonth && moment(end).isBefore(mEndDay)) {
                mEndDay = moment(end)
            }

            monthMap[cm] = {
                startDay: mStartDay,
                endDay: mEndDay
            }
        }

        return monthMap
    }

    function computeDayTicks(everyDay, monthMap) {
        let ticks = new Set()
        let endDay_ = moment()
        for (const month in monthMap) {
            if (Object.hasOwnProperty.call(monthMap, month)) {
                const { startDay, endDay } = monthMap[month];
                endDay_ = endDay
                let s = Number(moment(startDay).format("DD"))
                let e = Number(moment(endDay).format("DD"))

                let lastCache = moment(startDay)
                ticks.add(moment(lastCache).format("YYYY-MM-DD"))

                while (moment(lastCache).isBefore(moment(endDay))) {
                    let lastD = Number(moment(lastCache).format("DD"))
                    let delta = e - lastD
                    if (delta > everyDay * 1.5) {
                        delta = everyDay

                    }


                    ticks.add(moment(lastCache).format("YYYY-MM-DD"))
                    lastCache = moment(lastCache).add("day", delta + 1)
                }

                // ticks.add(moment(endDay).format("YYYY-MM-DD"))
            }
        }
        ticks.add(moment(endDay_).format("YYYY-MM-DD"))
        ticks = Array.from(ticks).map(t => moment(t).startOf("day"))

        // let tArr_ = []
        // for (let i = 0; i < ticks.length - 1; i += 1) {
        //     let bIndex = i;
        //     let eIndex = i + 1;

        // }



        let dayTicksDescArr = ticks.map(t => {
            return moment(t).format("YYYY-MM-DD")
        })
        console.log("dd", dayTicksDescArr)
        return ticks

    }

    function computeMonthTicks(monthMap) {

        let tickValues = Object.keys(monthMap).map((m) => {
            const { startDay } = monthMap[m]
            return startDay
        })

        return tickValues
    }

    function computeYearTicks(monthMap) {
        let tickValuesMap = {}

        Object.keys(monthMap).forEach((m) => {
            const { startDay, endDay } = monthMap[m]

            const year = moment(m).format("YYYY")

            if (!tickValuesMap[year]) {
                tickValuesMap[year] = {
                    yearStartDay: startDay,
                    yearEndDay: endDay
                }
            }

            const { yearStartDay, yearEndDay } = tickValuesMap[year]
            if (moment(yearEndDay).isBefore(endDay)) {
                tickValuesMap[year].yearEndDay = endDay
            }
        })

        let tickValues = []

        Object.keys(tickValuesMap).forEach(year => {
            const { yearStartDay } = tickValuesMap[year]
            tickValues.push(...[yearStartDay])
        })

        return tickValues

    }

    const xOffsets = dayTicks.map(d => {
        return positionComptedFn(d)
    })

    const pms = {
        xOffsets,
        yTop: height - dayX2Bottom,
        yBottom: height - padding
    }
    // drawXGrid(chart, pms)

    const xAxisYOffsets = [height - dayX2Bottom, height - dayX2Bottom - tickSize, height - dayX2Bottom - tickSize * 2, height - dayX2Bottom - tickSize * 3]


    return {
        positionComptedFn,
        xAxisYOffsets
    }
}

function drawXGrid(chart, params) {
    const { xOffsets, yTop, yBottom } = params
    chart.append("g")
        .classed("x-axis x-grid", true)
        .selectAll(".grid-line")
        .data(xOffsets)
        .join("g")
        .classed("grid-line", true)
        .append("line")
        .attr("x1", x => x)
        .attr("y1", yTop)
        .attr("x2", x => x)
        .attr("y2", yBottom)
        .attr("stroke", "red")
        .attr("opacity", "0.3");
}